package com.sz.admin.system.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;

/**
 * 静态文件服务控制器
 * 用于提供上传的图片文件访问
 *
 * @author sz-admin
 * @since 2025-01-13
 */
@Slf4j
@RestController
@RequestMapping("/uploads")
public class StaticFileController {

    @Value("${file.upload.path:./uploads}")
    private String uploadBasePath;

    @GetMapping("/{storageDir}/{dateDir}/{filename:.+}")
    public ResponseEntity<Resource> getFile(@PathVariable String storageDir,
                                           @PathVariable String dateDir,
                                           @PathVariable String filename) {
        try {
            // 构建文件路径
            Path filePath = Paths.get(uploadBasePath, storageDir, dateDir, filename);
            File file = filePath.toFile();

            if (!file.exists() || !file.isFile()) {
                log.warn("文件不存在: {}", filePath);
                return ResponseEntity.notFound().build();
            }

            // 检查文件是否在允许的目录内，防止路径遍历攻击
            Path uploadPath = Paths.get(uploadBasePath).toAbsolutePath().normalize();
            Path requestedPath = filePath.toAbsolutePath().normalize();
            
            if (!requestedPath.startsWith(uploadPath)) {
                log.warn("非法文件访问尝试: {}", requestedPath);
                return ResponseEntity.badRequest().build();
            }

            Resource resource = new FileSystemResource(file);
            
            // 根据文件扩展名设置Content-Type
            String contentType = getContentType(filename);
            
            log.debug("提供文件访问: {}", filePath);
            
            return ResponseEntity.ok()
                    .contentType(MediaType.parseMediaType(contentType))
                    .body(resource);

        } catch (Exception e) {
            log.error("获取文件失败: {}/{}/{}, error={}", storageDir, dateDir, filename, e.getMessage());
            return ResponseEntity.internalServerError().build();
        }
    }

    /**
     * 根据文件扩展名获取Content-Type
     */
    private String getContentType(String filename) {
        String extension = filename.substring(filename.lastIndexOf('.') + 1).toLowerCase();
        switch (extension) {
            case "jpg":
            case "jpeg":
                return "image/jpeg";
            case "png":
                return "image/png";
            case "gif":
                return "image/gif";
            case "bmp":
                return "image/bmp";
            case "webp":
                return "image/webp";
            default:
                return "application/octet-stream";
        }
    }
}